<?php
global $_QET;
session_start();
$_QET = $_REQUEST;
$json = file_get_contents('php://input');
if (!empty($json)) {
    $jsonData = json_decode($json, true) ?? [];
    $_QET = array_merge($_QET, $jsonData);
}

$configPath = __DIR__ . '/config.php'; // 定义配置文件路径

// 检查配置文件是否存在，如果不存在则创建并写入默认内容
if (!file_exists($configPath)) {
    // 默认网站配置信息
    $defaultSiteConf = [
        'title' => '我的导航网站',
        'docs' => '一个简洁高效的个人导航页面',
        'token' => '123456', // 后台管理token，留空则不启用
        'icp' => '豫ICP备2025123974号', // 备案号
        'email' => 'admin@example.com', // 联系邮箱
        'bg_pc_url' => 'https://lh.ithxs.com/apis.php?act=pc', // PC端背景图片地址
        'bg_mobile_url' => 'https://lh.ithxs.com/apis.php?act=pe' // 手机端背景图片地址
    ];

    // 默认链接数据，使用短数组语法且不带数字索引
    $defaultLinkData = [
        [
            'title' => '示例网站1',
            'description' => '这是一个示例网站的描述',
            'url' => 'https://example.com',
            'icon' => 'fas fa-globe', // Font Awesome 图标类名
            'clicks' => 0
        ],
        [
            'title' => '示例网站2',
            'description' => '这是另一个示例网站的描述',
            'url' => 'https://example.org',
            'icon' => 'fas fa-star', // Font Awesome 图标类名
            'clicks' => 0
        ]
    ];

    // 将默认配置数组转换为PHP代码字符串
    $phpCode = "<?php\n\n";
    // 使用短数组语法 [] 输出 $conf
    $phpCode .= "\$conf = " . preg_replace(['/^array \(/', '/\)$/'], ['[', ']'], var_export($defaultSiteConf, true)) . ";\n\n";
    // 使用短数组语法 [] 输出 $Data，并确保内部数组也是短语法且无数字索引
    $dataExport = var_export($defaultLinkData, true);
    // 替换外层 array() 为 []
    $dataExport = preg_replace('/^array \(/', '[', $dataExport);
    $dataExport = preg_replace('/\)$/', ']', $dataExport);
    // 替换内层 array() 为 []，并移除数字索引 '0 => array (' 替换为 'array ('
    $dataExport = preg_replace('/\s*\d+\s*=>\s*array\s*\(/', '[', $dataExport);
    $dataExport = preg_replace('/array\s*\(/', '[', $dataExport); // 处理可能未被上条规则匹配的内层array
    $dataExport = preg_replace('/\)/', ']', $dataExport); // 将所有剩余的 ) 替换为 ]

    $phpCode .= "\$Data = " . $dataExport . ";\n";

    // 尝试写入文件
    if (file_put_contents($configPath, $phpCode) === false) {
        die('无法创建或写入配置文件 config.php，请检查目录权限。');
    }
}

include $configPath;

// ============ 访问统计功能 ============
/**
 * 获取访问者真实IP地址
 * @return string
 */
function getVisitorIP()
{
    $ip = '';
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (isset($_SERVER['HTTP_X_REAL_IP'])) {
        $ip = $_SERVER['HTTP_X_REAL_IP'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    }
    // 如果有多个IP，取第一个
    if (strpos($ip, ',') !== false) {
        $ip = trim(explode(',', $ip)[0]);
    }
    return $ip;
}

/**
 * 异步获取IP地理位置信息
 * @param string $ip IP地址
 * @return array|null 位置信息或null
 */
function getIPLocationInfo($ip)
{
    // 跳过本地IP和内网IP
    if (in_array($ip, ['127.0.0.1', '::1', 'localhost']) || 
        preg_match('/^192\.168\./', $ip) || 
        preg_match('/^10\./', $ip) || 
        preg_match('/^172\.(1[6-9]|2[0-9]|3[0-1])\./', $ip)) {
        return null;
    }
    
    try {
        $url = "https://api.songzixian.com/api/ip?dataSource=GLOBAL_IP&ip=" . urlencode($ip);
        
        // 设置超时时间，避免阻塞
        $context = stream_context_create([
            'http' => [
                'timeout' => 3,
                'ignore_errors' => true
            ]
        ]);
        
        $response = @file_get_contents($url, false, $context);
        
        if ($response === false) {
            return null;
        }
        
        $result = json_decode($response, true);
        
        if (isset($result['code']) && $result['code'] === 200 && isset($result['data'])) {
            return [
                'country' => $result['data']['country'] ?? '未知',
                'province' => $result['data']['province'] ?? '',
                'city' => $result['data']['city'] ?? '',
                'isp' => $result['data']['isp'] ?? '未知运营商',
                'latitude' => $result['data']['latitude'] ?? 0,
                'longitude' => $result['data']['longitude'] ?? 0,
                'last_update' => date('Y-m-d H:i:s')
            ];
        }
    } catch (Exception $e) {
        error_log("获取IP位置失败: " . $e->getMessage());
    }
    
    return null;
}

/**
 * 测试IP位置功能（用于开发环境）
 * @param string $testIP 测试用的IP地址
 * @return bool 是否成功
 */
function testIPLocation($testIP = '8.8.8.8')
{
    // 获取位置信息
    $locationInfo = getIPLocationInfo($testIP);
    
    if ($locationInfo) {
        // 保存到文件
        saveIPLocation($testIP, $locationInfo);
        
        // 同时更新访问统计，添加这个测试IP
        $statsFile = __DIR__ . '/visit_stats.json';
        $fp = fopen($statsFile, 'c+');
        if ($fp && flock($fp, LOCK_EX)) {
            $fileSize = filesize($statsFile);
            $statsData = [];
            if ($fileSize > 0) {
                $content = fread($fp, $fileSize);
                $statsData = json_decode($content, true) ?? [];
            }
            
            // 添加测试IP到今日访问
            if (!isset($statsData['today_ips'])) {
                $statsData['today_ips'] = [];
            }
            if (!in_array($testIP, $statsData['today_ips'])) {
                $statsData['today_ips'][] = $testIP;
            }
            
            // 添加到总IP
            if (!isset($statsData['total_ips'])) {
                $statsData['total_ips'] = [];
            }
            if (!in_array($testIP, $statsData['total_ips'])) {
                $statsData['total_ips'][] = $testIP;
            }
            
            // 写回文件
            ftruncate($fp, 0);
            rewind($fp);
            fwrite($fp, json_encode($statsData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
            flock($fp, LOCK_UN);
        }
        if ($fp) fclose($fp);
        
        return true;
    }
    
    return false;
}

/**
 * 保存IP位置信息
 * @param string $ip IP地址
 * @param array $locationInfo 位置信息
 */
function saveIPLocation($ip, $locationInfo)
{
    $locationFile = __DIR__ . '/ip_locations.json';
    
    $fp = fopen($locationFile, 'c+');
    if (!$fp) {
        return false;
    }
    
    if (flock($fp, LOCK_EX)) {
        // 读取现有数据
        $fileSize = filesize($locationFile);
        $data = [];
        if ($fileSize > 0) {
            $content = fread($fp, $fileSize);
            $data = json_decode($content, true) ?? [];
        }
        
        // 初始化数据结构
        if (empty($data)) {
            $data = [
                'ip_locations' => [],
                'location_stats' => []
            ];
        }
        
        // 保存IP位置信息
        $data['ip_locations'][$ip] = $locationInfo;
        
        // 生成地理位置键（国家-省份-城市）
        $locationKey = trim($locationInfo['country'] . '-' . $locationInfo['province'] . '-' . $locationInfo['city'], '-');
        
        // 更新地区统计
        if (!isset($data['location_stats'][$locationKey])) {
            $data['location_stats'][$locationKey] = [
                'count' => 0,
                'ips' => [],
                'display_name' => $locationInfo['province'] ?: $locationInfo['country']
            ];
        }
        
        // 增加该地区访问次数
        $data['location_stats'][$locationKey]['count']++;
        
        // 记录IP（避免重复）
        if (!in_array($ip, $data['location_stats'][$locationKey]['ips'])) {
            $data['location_stats'][$locationKey]['ips'][] = $ip;
        }
        
        // 写回文件
        ftruncate($fp, 0);
        rewind($fp);
        fwrite($fp, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
        
        flock($fp, LOCK_UN);
    }
    
    fclose($fp);
    return true;
}

/**
 * 获取或更新IP位置
 * @param string $ip IP地址
 * @return array|null 位置信息
 */
function getOrFetchIPLocation($ip)
{
    $locationFile = __DIR__ . '/ip_locations.json';
    
    // 读取已保存的位置信息
    if (file_exists($locationFile)) {
        $content = file_get_contents($locationFile);
        $data = json_decode($content, true) ?? [];
        
        // 如果已有该IP的位置信息，直接返回
        if (isset($data['ip_locations'][$ip])) {
            return $data['ip_locations'][$ip];
        }
    }
    
    // 没有该IP的位置信息，异步获取
    $locationInfo = getIPLocationInfo($ip);
    
    if ($locationInfo) {
        // 保存到文件
        saveIPLocation($ip, $locationInfo);
        return $locationInfo;
    }
    
    return null;
}

/**
 * 确保logs目录存在
 */
function ensureLogsDirectory()
{
    $logsDir = __DIR__ . '/logs';
    if (!is_dir($logsDir)) {
        mkdir($logsDir, 0755, true);
    }
    return $logsDir;
}

/**
 * 保存每日访问数据到logs目录
 */
function saveDailyVisitLog($date, $dailyData)
{
    $logsDir = ensureLogsDirectory();
    $dailyLogFile = $logsDir . '/visit_' . $date . '.json';
    
    // 如果当日日志文件已存在，读取并合并数据
    $existingData = [];
    if (file_exists($dailyLogFile)) {
        $content = file_get_contents($dailyLogFile);
        $existingData = json_decode($content, true) ?? [];
    }
    
    // 合并数据
    $mergedData = array_merge($existingData, $dailyData);
    
    // 保存到当日日志文件
    file_put_contents($dailyLogFile, json_encode($mergedData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}

/**
 * 记录访问统计
 * 高效方式：使用JSON文件存储，避免数据库开销
 * 新增功能：每天单独存储访问数据到logs目录
 */
function recordVisit()
{
    $statsFile = __DIR__ . '/visit_stats.json';
    $ip = getVisitorIP();
    $today = date('Y-m-d');
    $currentTime = time();
    
    // 获取文件锁，避免并发写入问题
    $fp = fopen($statsFile, 'c+');
    if (!$fp) {
        return false;
    }
    
    if (flock($fp, LOCK_EX)) {
        // 读取现有统计数据
        $fileSize = filesize($statsFile);
        $statsData = [];
        if ($fileSize > 0) {
            $content = fread($fp, $fileSize);
            $statsData = json_decode($content, true) ?? [];
        }
        
        // 初始化数据结构
        if (empty($statsData)) {
            $statsData = [
                'last_date' => $today,
                'today_visits' => 0,
                'today_ips' => [],
                'total_visits' => 0,
                'total_ips' => []
            ];
        }
        
        // 检查是否跨天，如果跨天则保存前一天的数据并重置当天数据
        if ($statsData['last_date'] !== $today) {
            // 保存前一天的完整数据到logs目录
            if (!empty($statsData['last_date']) && $statsData['today_visits'] > 0) {
                $previousDayData = [
                    'date' => $statsData['last_date'],
                    'total_visits' => $statsData['today_visits'],
                    'unique_visitors' => count($statsData['today_ips']),
                    'visitor_ips' => $statsData['today_ips'],
                    'summary' => [
                        'visits' => $statsData['today_visits'],
                        'unique_ips' => count($statsData['today_ips']),
                        'date_saved' => date('Y-m-d H:i:s')
                    ]
                ];
                saveDailyVisitLog($statsData['last_date'], [$previousDayData]);
            }
            
            // 重置当天数据
            $statsData['last_date'] = $today;
            $statsData['today_visits'] = 0;
            $statsData['today_ips'] = [];
        }
        
        // 更新今日访问数
        $statsData['today_visits']++;
        
        // 更新今日IP（如果是新IP）
        if (!in_array($ip, $statsData['today_ips'])) {
            $statsData['today_ips'][] = $ip;
        }
        
        // 更新总访问数
        $statsData['total_visits']++;
        
        // 更新总IP（如果是新IP）
        if (!in_array($ip, $statsData['total_ips'])) {
            $statsData['total_ips'][] = $ip;
        }
        
        // 写回文件
        ftruncate($fp, 0);
        rewind($fp);
        fwrite($fp, json_encode($statsData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
        
        flock($fp, LOCK_UN);
    }
    
    fclose($fp);
    
    // 同时记录详细的访问记录到当日日志
    $visitRecord = [
        'timestamp' => $currentTime,
        'datetime' => date('Y-m-d H:i:s', $currentTime),
        'ip' => $ip,
        'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
        'referer' => $_SERVER['HTTP_REFERER'] ?? '',
        'request_uri' => $_SERVER['REQUEST_URI'] ?? ''
    ];
    
    // 异步保存详细访问记录和获取IP位置
    register_shutdown_function(function() use ($ip, $today, $visitRecord) {
        // 保存详细访问记录到当日日志
        $logsDir = ensureLogsDirectory();
        $detailLogFile = $logsDir . '/visit_detail_' . $today . '.json';
        
        $detailRecords = [];
        if (file_exists($detailLogFile)) {
            $content = file_get_contents($detailLogFile);
            $detailRecords = json_decode($content, true) ?? [];
        }
        
        $detailRecords[] = $visitRecord;
        file_put_contents($detailLogFile, json_encode($detailRecords, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
        
        // 获取IP位置信息
        getOrFetchIPLocation($ip);
    });
    
    return true;
}

/**
 * 读取历史访问数据
 */
function getHistoricalVisitData($days = 7)
{
    $logsDir = __DIR__ . '/logs';
    $historicalData = [];
    
    if (!is_dir($logsDir)) {
        return $historicalData;
    }
    
    for ($i = 0; $i < $days; $i++) {
        $date = date('Y-m-d', strtotime("-{$i} days"));
        $logFile = $logsDir . '/visit_' . $date . '.json';
        
        if (file_exists($logFile)) {
            $content = file_get_contents($logFile);
            $dayData = json_decode($content, true) ?? [];
            
            if (!empty($dayData)) {
                $historicalData[$date] = $dayData[0] ?? [];
            }
        }
    }
    
    return $historicalData;
}

/**
 * 获取地区访问统计
 */
function getLocationStats()
{
    $logsDir = __DIR__ . '/logs';
    $locations = [];
    
    if (!is_dir($logsDir)) {
        return $locations;
    }
    
    // 读取最近7天的详细访问记录
    for ($i = 0; $i < 7; $i++) {
        $date = date('Y-m-d', strtotime("-{$i} days"));
        $detailLogFile = $logsDir . '/visit_detail_' . $date . '.json';
        
        if (file_exists($detailLogFile)) {
            $content = file_get_contents($detailLogFile);
            $records = json_decode($content, true) ?? [];
            
            foreach ($records as $record) {
                $ip = $record['ip'] ?? '';
                if ($ip && $ip !== '127.0.0.1') {
                    // 这里可以集成IP地理位置查询
                    // 暂时使用简单的地区分类
                    $location = getSimpleLocationByIP($ip);
                    if ($location) {
                        $locations[$location] = ($locations[$location] ?? 0) + 1;
                    }
                }
            }
        }
    }
    
    // 按访问量排序
    arsort($locations);
    return array_slice($locations, 0, 10); // 返回前10个地区
}

/**
 * 简单的IP地理位置判断（可以后续集成更精确的API）
 */
function getSimpleLocationByIP($ip)
{
    // 这里可以集成第三方IP地理位置API
    // 暂时返回一些示例数据
    $ipRanges = [
        '127.0.0.1' => '本地',
        '192.168.' => '局域网',
        '10.' => '内网',
        '172.' => '内网'
    ];
    
    foreach ($ipRanges as $range => $location) {
        if (strpos($ip, $range) === 0) {
            return $location;
        }
    }
    
    // 根据IP段简单判断地区（这只是示例，实际应该使用专业的IP地理位置库）
    $firstOctet = intval(explode('.', $ip)[0]);
    
    if ($firstOctet >= 1 && $firstOctet <= 126) {
        return '国内';
    } elseif ($firstOctet >= 128 && $firstOctet <= 191) {
        return '亚洲';
    } elseif ($firstOctet >= 192 && $firstOctet <= 223) {
        return '欧美';
    } else {
        return '其他地区';
    }
}

/**
 * 获取当天链接点击数据
 * @return array
 */
function getDailyClickStats()
{
    $clickStatsFile = __DIR__ . '/daily_clicks.json';
    $today = date('Y-m-d');
    
    // 默认数据
    $clickStats = [
        'last_date' => $today,
        'today_clicks' => 0,
        'total_clicks' => 0,
        'today_links' => [],
        'click_details' => []
    ];
    
    if (file_exists($clickStatsFile)) {
        $content = file_get_contents($clickStatsFile);
        $clickData = json_decode($content, true) ?? [];
        
        // 检查是否跨天
        if (isset($clickData['last_date']) && $clickData['last_date'] !== $today) {
            $clickData['today_clicks'] = 0;
            $clickData['today_links'] = [];
            $clickData['click_details'] = [];
        }
        
        $clickStats = [
            'last_date' => $clickData['last_date'] ?? $today,
            'today_clicks' => $clickData['today_clicks'] ?? 0,
            'total_clicks' => $clickData['total_clicks'] ?? 0,
            'today_links' => $clickData['today_links'] ?? [],
            'click_details' => $clickData['click_details'] ?? []
        ];
    }
    
    return $clickStats;
}

/**
 * 获取历史链接点击数据
 * @param int $days 天数
 * @return array
 */
function getHistoricalClickData($days = 7)
{
    $logsDir = __DIR__ . '/logs/clicks';
    $historicalData = [];
    
    if (!is_dir($logsDir)) {
        return $historicalData;
    }
    
    for ($i = 0; $i < $days; $i++) {
        $date = date('Y-m-d', strtotime("-{$i} days"));
        $logFile = $logsDir . '/clicks_' . $date . '.json';
        
        if (file_exists($logFile)) {
            $content = file_get_contents($logFile);
            $dayData = json_decode($content, true) ?? [];
            
            if (!empty($dayData)) {
                $historicalData[$date] = $dayData;
            }
        }
    }
    
    return $historicalData;
}

/**
 * 获取链接点击排行榜
 * @param int $limit 返回数量
 * @return array
 */
function getTopClickedLinks($limit = 10)
{
    $clickStats = getDailyClickStats();
    $todayLinks = $clickStats['today_links'] ?? [];
    
    // 按点击次数排序
    uasort($todayLinks, function($a, $b) {
        return ($b['clicks'] ?? 0) - ($a['clicks'] ?? 0);
    });
    
    return array_slice($todayLinks, 0, $limit, true);
}

/**
 * 获取访问统计数据
 * 增强版：包含历史数据和地区统计
 * @return array
 */
function getVisitStats()
{
    $statsFile = __DIR__ . '/visit_stats.json';
    
    // 基础统计数据
    $baseStats = [
        'last_date' => date('Y-m-d'),
        'today_visits' => 0,
        'today_unique' => 0,
        'total_visits' => 0,
        'total_unique' => 0
    ];
    
    if (file_exists($statsFile)) {
        $content = file_get_contents($statsFile);
        $statsData = json_decode($content, true) ?? [];
        
        // 检查是否跨天
        $today = date('Y-m-d');
        if (isset($statsData['last_date']) && $statsData['last_date'] !== $today) {
            $statsData['today_visits'] = 0;
            $statsData['today_ips'] = [];
        }
        
        $baseStats = [
            'last_date' => $statsData['last_date'] ?? $today,
            'today_visits' => $statsData['today_visits'] ?? 0,
            'today_unique' => count($statsData['today_ips'] ?? []),
            'total_visits' => $statsData['total_visits'] ?? 0,
            'total_unique' => count($statsData['total_ips'] ?? [])
        ];
    }
    
    // 获取历史数据
    $historicalData = getHistoricalVisitData(7);
    
    // 获取地区统计
    $locationStats = getLocationStats();
    
    // 获取当天链接点击数据
    $clickStats = getDailyClickStats();
    
    // 合并所有统计数据
    return array_merge($baseStats, $clickStats, [
        'historical' => $historicalData,
        'locations' => $locationStats,
        'stats_generated_at' => date('Y-m-d H:i:s')
    ]);
}

// 自动记录访问（排除后台管理页面和API请求）
$currentScript = basename($_SERVER['SCRIPT_FILENAME'] ?? '');
if ($currentScript === 'index.php') {
    recordVisit();
}
// ============ 访问统计功能结束 ============


/**
 * @param $string
 * @return array|mixed|string
 * 数据安全过滤
 */
function daddslashes($string)
{
    if (is_array($string)) {
        foreach ($string as $key => $val) {
            $val = SecurityFiltering($val);
            $string[$key] = daddslashes($val);
            $string[$key] = saddslashes($string[$key]);
            if (($key == 'file' || strstr($key, 'imageData') || strstr($key, 'VideoData')) && !empty($val['tmp_name'])) {
                $string[$key]['tmp_name'] = SecurityFiltering($val['tmp_name']);
            }
        }
    } else {
        $string = htmlspecialchars($string);
        $string = saddslashes($string);
    }
    return $string;
}
function saddslashes($string)
{
    if (is_array($string)) {
        foreach ($string as $key => $val) {
            $string[$key] = saddslashes($val);
        }
    } else {
        $string = addslashes($string);
    }
    return $string;
}

/**
 * @param $str_string
 * @return mixed
 * 安全过滤
 */
function SecurityFiltering($str_string)
{
    $_arr_dangerRegs = [
        "/on(afterprint|beforeprint|beforeunload|error|haschange|load|message|offline|online|pagehide|pageshow|popstate|redo|resize|storage|undo|unload|blur|change|contextmenu|focus|formchange|forminput|input|invalid|reset|select|submit|keydown|keypress|keyup|click|dblclick|drag|dragend|dragenter|dragleave|dragover|dragstart|drop|mousedown|mousemove|mouseout|mouseover|mouseup|mousewheel|scroll|abort|canplay|canplaythrough|durationchange|emptied|ended|error|loadeddata|loadedmetadata|loadstart|pause|play|playing|progress|ratechange|readystatechange|seeked|seeking|stalled|suspend|timeupdate|volumechange|waiting)\s*=\s*(\"|')?\S*(\"|')?/i",
        "/\w+\s*=\s*(\"|')?(java|vb)script:\S*(\"|')?/i",
        '/(document|location)\s*\.\s*\S*/i',
        '/(eval|alert|prompt|msgbox)\s*\(.*\)/i',
        '/expression\s*:\s*\S*/i',
        '/show\s+(databases|tables|index|columns)/i',
        '/create\s+(database|table|(unique\s+)?index|view|procedure|proc)/i',
        '/alter\s+(database|table)/i',
        '/drop\s+(database|table|index|view|column)/i',
        '/backup\s+(database|log)/i',
        '/truncate\s+table/i',
        '/replace\s+view/i',
        '/(add|change)\s+column/i',
        '/(select|insert|update|delete)\s+\S*\s+from/i',
        '/insert\s+into/i',
        '/load_file\s*\(.*\)/i',
        "/(outfile|infile)\s+(\"|')?\S*(\"|')/i",
        "/<(\\/?)(script|i?frame|bgsound|applet|embed|blink|i?layer|style|base|html|body|title|link|meta|object|\\?|\\%)([^>]*?)>/isU",
        '/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU',
        "/(select|insert|delete\'|\/\*|\.\.\/|\.\/|union|into|load_file|outfile|dump)/is"
    ];

    $_str_return = $str_string;

    foreach ($_arr_dangerRegs as $_value) {
        $_str_return = preg_replace($_value, '', $_str_return);
    }

    return $_str_return;
}
